<?php
/**
******************************************************************************
******************************************************************************
 *          MySQLAbstractDAO.php
 * @package data
 * 
 * @author  j.garcia@irobase.net
 * @date    24 déc. 07
 * 
 *                   
******************************************************************************
 */

require_once 'classes/common/util/DateSimple.class.php';

/**
 * @package data 
 * La classe Abstraite pour les objets qui travaillent avec la BD MySQL 
 */
 abstract class BaseDAO {

    // la valeur du champ $connection est une connection active à la BD     
    protected $_oDbConn;
    
    // @todo Trouver la façon pour que tous les objets definissent cette constante !
    static protected $_NULL = null;

    const   _MYSQL_DATE_SEPARATEUR = '-';
    const   _MYSQL_TIME_SEPARATEUR = ':';
    
    const   _MYSQL_TYPE_TEXTE   = 'text';
    const   _MYSQL_TYPE_LONG    = 'long';
    const   _MYSQL_TYPE_INT     = 'int';
    const   _MYSQL_TYPE_DOUBLE  = 'double';
    const   _MYSQL_TYPE_DATE    = 'date';
    const   _MYSQL_TYPE_DATETIME    = 'datetime';
    const   _MYSQL_TYPE_DEFINED = 'defined';
    
    const   _MYSQL_NULL_VALUE   = 'NULL';
    
    const   _MYSQL_TRUE_VALUE   = 'TRUE';
    const   _MYSQL_FALSE_VALUE  = 'FALSE';
    
    const   _MYSQL_DATE_ZERO    = '00000000000000';
    
     
    //*************************************************************************
    //*************************************************************************
    
    /**
     * Constructeur pour cette classe
     *
     */
    public function __construct(& $connection) {
        $this->_oDbConn = & $connection;
    }


    
    /**
     * Retourne une chaîne de caractères, qui représente une date pour MySQL.
     * Le format de Date de MySQL = 'AAAA-mm-jj'
     *
     * @param  DateSimple   $date      
     * @return string       La chaîne de caractères avec le format de Date pour MySQL
     */
    protected function getMySQLDateFormat(DateSimple & $date) {

        if ($date->getEstDateZero()) return self::_MYSQL_DATE_ZERO;
        
        //Un objet de date valide
        return $date->getAnnee() . self::_MYSQL_DATE_SEPARATEUR . $date->getMois() . self::_MYSQL_DATE_SEPARATEUR . $date->getJour();
    }
    
    
    /**
     * Retourne une chaîne de caractères, qui représente une date pour MySQL.
     * Le format de Date de MySQL = 'AAAA-mm-jj'
     *
     * @param DateSimple $date
     * @return unknown
     */
    protected function getMySQLDateTimeFormat(DateSimple & $date) {

        if ($date->getEstDateZero()) return self::_MYSQL_DATE_ZERO;

        $txtDateAvecFormat =  $this->getMySQLDateFormat($date);
        
        $txtTimeAvecFormat = '';
        
        if ( $date->getHeure() !== null ) {
            $txtTimeAvecFormat =  ' ' . $date->getHeure() . self::_MYSQL_TIME_SEPARATEUR . $date->getMinute() . self::_MYSQL_TIME_SEPARATEUR . $date->getSecond();    
        }
        
        //Un objet de date valide
        return $txtDateAvecFormat . $txtTimeAvecFormat;
    }
    
    

    /**
     * Applique un format MySQL au valeur envoyé, en tenant compte d'autres 
     * paramètres, comme son type par exemple.
     * 
     * TODO : Attention ! Cette fonction est basée sur la fonction du même nom 
     * trouvée dans mes_fonctions.php ou globals.php. 
     *
     * @param unknown_type $theValue   La valeur a formatter
     * @param unknown_type $theType    Les types acceptés sont les constantes 
     * suivantes :
     * <ul> <li>_MYSQL_TYPE_TEXTE</li>
     *      <li>_MYSQL_TYPE_LONG</li>
     *      <li>_MYSQL_TYPE_DOUBLE</li>
     *      <li>_MYSQL_TYPE_DATE</li>
     *      <li>_MYSQL_TYPE_DEFINED</li> </ul>
     * @param unknown_type $theDefinedValue
     * @param unknown_type $theNotDefinedValue
     * @return unknown                 La nouvelle valeur après avoir été formatée.
     */
    protected function getSQLValueString($theValue, $theType, $theDefinedValue = "", $theNotDefinedValue = "") {

        switch ($theType) {
            case 'date':

                if ( !($theValue instanceof DateSimple) ) {
                    return "NULL";
                }
                

                $outputValue = $this->getMySQLDateFormat( $theValue );                
                return ($outputValue != "") ? "'" . $outputValue . "'" : "NULL";

            case 'datetime':

                if ( !($theValue instanceof DateSimple) ) {
                    return "NULL";
                }

                $outputValue = $this->getMySQLDateTimeFormat( $theValue );
                return ($outputValue != "") ? "'" . $outputValue . "'" : "NULL";
        }
        
        // sinon ...
        
        
        $theValue = trim(mysql_real_escape_string($theValue));
        
        switch ($theType) {
        case "text":
          $theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
          break;    
        case "long":
        case "int":
            $theValue = ($theValue != "") ? bcadd($theValue,0) : "0";
            break;          
        case "double":
          $theValue = ($theValue != "") ? "'" . doubleval($theValue) . "'" : "0";
          break;

        case "defined":
          $theValue = ($theValue != "") ? $theDefinedValue : $theNotDefinedValue;
          break;
        }
        return $theValue;
    }
    
    
    
    /**
     * @todo Enter description here...
     * Return un nouvel objet DateSimple
     * $dateBDD est une chaîne de la forme 'aaaa-mm-dd' ou 'aaaa-mm-dd hh:mm:ss' 
     * 
     * @param unknown_type $dateBDD
     * @return unknown
     */
    protected function convertToDateSimple($dateBDD) {

        if (!$dateBDD) {
            return null;
        }
        
        $dateString = str_replace(self::_MYSQL_DATE_SEPARATEUR, DateSimple::_DATE_SEPARATEUR, $dateBDD);
        $timeString = null;
        
        // Si l'heure est soumise
        if (strpos($dateBDD, self::_MYSQL_TIME_SEPARATEUR) ) {
            $timeString = substr($dateString,-8);
            $dateString = substr($dateString,0,10);
        }
        
        // Formatter la Date pour l'application
        $dateArray = split(DateSimple::_DATE_SEPARATEUR, $dateString);

        $jour  = $dateArray[2];
        $mois  = $dateArray[1];
        $annee = $dateArray[0];
        
        if ( ($jour == 0) || ($mois == 0) || ($annee == 0) ) {
            return null;
        }
        
        $dateString = $jour . DateSimple::_DATE_SEPARATEUR . $mois . DateSimple::_DATE_SEPARATEUR . $annee;
        
        return new DateSimple($dateString, $timeString);
    }
    
    
    /**
     * Retourne le dernier identifiant automatiquement généré par une colonne AUTO_INCREMENT.
     * 
     * Utilise la fonction MySQL 'LAST_INSERT_ID'. 
     *
     * @return int
     */
    protected function findLastId() {
        
        $sql = 'SELECT LAST_INSERT_ID() as last';
        
        $rs  = mysql_query($sql, $this->_oDbConn);

        //Si erreur ...
        if (!$rs) {
            throw new CommonSystemException (CommonSystemException::_ERR_BD);
        }
        
        $totalRows = mysql_num_rows($rs);
    
        if ($totalRows > 0) {

            if ($row = mysql_fetch_assoc($rs)){
                return $row['last']; 
            }
        }

        return null;
    }
    
}
 
?>